import React, { useContext } from 'react';
import { Form, Input, InputNumber, Typography, Popover, message, Empty, Spin, Alert } from 'antd';
import { get as getPath } from 'object-path';
import LimitInput from '@/components/LimitInput';
// import { AppellationSelect } from '@/pages/Organization/OrgFlow/components';
import { getDepartmentDetail, getRelativeOrganizations } from '../../services';
import styles from './index.less';
import { OrganizationContext } from '../../OrgTree/store/context';

const getDecimalsTotal = number => {
    const decimals = number.toString().split('.')[1] || [];
    return decimals.length;
};

const Department = ({ form, isAddPage, query, setLoading, showTips }) => {
    const { getFieldDecorator, setFieldsValue } = form;
    const [info, setInfo] = React.useState(null);
    const [relativeList, setRelativeList] = React.useState(null);
    const organizationContext = useContext(OrganizationContext);

    const getDetail = async () => {
        setLoading(true);
        const res = await getDepartmentDetail(query && query.organizationCode);
        const { data, code } = res;
        if (code === 10000) {
            setInfo(data);
        }
        setLoading(false);
    };

    const computedRelativeListData = serveData => {
        let combineData = [...serveData];
        // 获取已存在统计的节点, 用来计算排序号. 解决同时添加两个节点时, 排序号需要包含上个添加的记录的排序号
        const existCurrentLevelNode = organizationContext.state?.submitData.filter(
            item => query.organizationPath === item.data.parentOrganizationPath
        );
        // 合并新增的节点, 排除掉删除掉的节点
        existCurrentLevelNode.forEach(item => {
            if (item.type === 'add') {
                combineData.push(item.data);
            } else if (item.type === 'delete') {
                combineData.splice(
                    combineData.findIndex(d => d.organizationCode === item.data.organizationCode),
                    1
                );
            }
        });
        // 按排序进行重拍
        combineData = combineData.sort((a, b) => a.sort - b.sort);
        setRelativeList(combineData);
    };

    const getRelativeList = async orgCode => {
        if (!orgCode) {
            computedRelativeListData([]);
            return;
        }
        setLoading(true);
        // 拉取服务端数据
        const res = await getRelativeOrganizations(orgCode);
        const { data, code, msg } = res;
        if (code === 10000) {
            const serveData = (Array.isArray(data) && data) || [];
            computedRelativeListData(serveData);
        } else {
            message.error(msg);
        }
        setLoading(false);
    };

    React.useEffect(() => {
        if (!isAddPage && query) {
            getDetail().then();
        }
        if (isAddPage && query) {
            getRelativeList(query && query.organizationCode).then();
        }
    }, [query]);

    React.useEffect(() => {
        if (!isAddPage && info) {
            getRelativeList(getPath(info, 'parentOrganizationCode', '')).then();
        }
    }, [info]);

    // 默认的排序号
    const defaultSort = React.useMemo(() => {
        if (info && relativeList) {
            const existIndex = relativeList.findIndex(item => item.organizationPath === info.organizationPath);
            return existIndex === -1 ? null : existIndex;
        }
        return null;
    }, [info, relativeList]);

    /**
     * 计算排序序号
     *
     * 因为排序是整数类型的! 为了解决在 3 与 4 中间插入排序, 前端使用 小数 的形式来处理
     * 但是又不允许用户输入小数
     * 所以界面上使用整数排序, 实际上保存的是小数
     * 因为服务端不接受小数类型的排序号, 所以会在提交数据的时候把同级节点的排序发送给服务端
     */
    const computedSort = sort => {
        // 因为可能出现插入的位置是这样的: 3,4 之间  2.98 与 2.99 之间, 所以要依据小数位数进行处理
        // 计算小数数位
        const decimalsLength = getDecimalsTotal(sort);
        // 运算的精度
        const precision = Math?.pow(10, decimalsLength + 1);
        // 先减去一个比较小的数字
        let result = Math.round((sort - 1 / precision) * precision) / precision;
        // 检查这个排序是否被占用 (例如连续插入位置是 2,3,4 这样的情况)
        const existSortArr = relativeList.map(item => item.sort);
        // 如果被占用就在这个基础上加上一个更小的数字, 结果例如  2.9 2.91 3
        while (existSortArr.includes(result)) {
            result = Math.round((result + 1 / precision / 10) * (precision * 10)) / (precision * 10);
        }
        return result;
    };

    // 获取排序
    const getSort = (arr, sort) => {
        // 过滤掉助理团(排序是999)
        const filteredValue = arr.filter(item => item.sort < 999);
        // 查找插入的位置, 判断这个位置是否有值, 有值的话, 排序要进行小数化, 没值的话就直接插入
        const oldPositionValue = filteredValue[sort ? sort - 1 : 0];
        return oldPositionValue?.sort !== undefined && oldPositionValue?.sort !== null
            ? computedSort(oldPositionValue.sort)
            : sort - 1;
    };

    // 表单问题, 用户输入的是整数, 但实际要处理成小数, 所以要用两个字段孔子
    // 当 _sort 变更的时候, 计算排序 赋值给 sort 字段
    const handleSortInputChange = value => {
        setFieldsValue({ sort: getSort(relativeList, value) });
    };
    // const getSupervisorValue = () => {
    //     if (info?.titleValue) {
    //         return {
    //             key: info?.titleValue,
    //             label: info?.titleName
    //         };
    //     }
    //     return undefined;
    // };
    // 排序的预览图
    const popoverContent = relativeList ? (
        <div style={{ minWidth: 250, maxWidth: 500, maxHeight: 250, overflow: 'auto' }}>
            {relativeList?.map((item, index) => (
                <div key={item.organizationCode} style={{ display: 'flex', justifyContent: 'space-between' }}>
                    <Typography.Paragraph ellipsis>{item.organizationName}</Typography.Paragraph>
                    <div style={{ marginLeft: 10, marginRight: 10, flexShrink: 0, width: '6em' }}>
                        {/* 用户看到的是连续的排序号 */}
                        排序号：{item.sort === 999 ? 999 : index + 1}
                    </div>
                </div>
            ))}
            {relativeList.length <= 0 && <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
        </div>
    ) : null;

    return (
        <Spin spinning={!relativeList}>
            {showTips ? (
                <Alert
                    className={styles.alertCss}
                    message="新增机构为上级机构的第一个子机构，则会默认承接上级机构除主管外的员工和岗位。"
                    type="info"
                    showIcon
                    banner
                />
            ) : null}

            <Form className={styles.formWrap}>
                <Form.Item label="上级机构">
                    {isAddPage ? getPath(query, 'organizationName', '') : getPath(info, 'parentOrganizationName', '')}
                </Form.Item>
                <Form.Item label="部门名称(中文)">
                    {getFieldDecorator('organizationName', {
                        initialValue: getPath(info, 'organizationName', ''),
                        rules: [
                            {
                                required: true,
                                message: '部门名称(中文)不能为空',
                                whitespace: true
                            },
                            {
                                validator(_, value, callback) {
                                    if (value.indexOf('/') > -1 || value.indexOf(':') > -1) {
                                        callback('不允许输入:或/');
                                    } else {
                                        callback();
                                    }
                                }
                            }
                        ]
                    })(<Input placeholder="请输入部门名称(中文)" allowClear maxLength={150} />)}
                </Form.Item>
                <Form.Item label="部门名称(英文)">
                    {getFieldDecorator('organizationNameEnglish', {
                        initialValue: getPath(info, 'organizationNameEnglish', ''),
                        rules: [
                            {
                                validator(_, value, callback) {
                                    if (value.indexOf('/') > -1 || value.indexOf(':') > -1) {
                                        callback('不允许输入:或/');
                                    } else {
                                        callback();
                                    }
                                }
                            }
                        ]
                    })(<Input placeholder="请输入部门名称(英文)" allowClear maxLength={150} />)}
                </Form.Item>
                <Form.Item label="排序号">
                    {getFieldDecorator('sort', { initialValue: defaultSort })}
                    <Popover
                        content={popoverContent}
                        title="当前排序"
                        trigger="focus"
                        placement="bottomRight"
                        getPopupContainer={trigger => trigger.parentNode}
                    >
                        {getFieldDecorator('_sort', {
                            initialValue: defaultSort,
                            rules: [
                                {
                                    required: true,
                                    message: '排序号不能为空'
                                }
                            ]
                        })(
                            <InputNumber
                                min={1}
                                max={999}
                                precision={0}
                                placeholder="请输入排序号"
                                style={{ width: '100%' }}
                                onChange={handleSortInputChange}
                            />
                        )}
                    </Popover>
                </Form.Item>
                {/* <Form.Item label="主管称呼">
                    {getFieldDecorator('supervisorName', {
                        initialValue: getSupervisorValue(),
                        rules: [
                            {
                                required: true,
                                message: '主管称呼不能为空'
                            }
                        ]
                    })(<AppellationSelect />)}
                </Form.Item> */}
                <Form.Item label="部门电话">
                    {getFieldDecorator('phone', {
                        initialValue: getPath(info, 'phone', ''),
                        rules: [
                            {
                                validator(rule, value, callback) {
                                    const regex = /[a-zA-Z\u4e00-\u9fa5]+/g;
                                    if (value && regex.test(value)) {
                                        callback('部门电话不能包含中英文字符');
                                    }
                                    callback();
                                }
                            }
                        ]
                    })(<Input placeholder="请输入部门电话" allowClear maxLength={20} />)}
                </Form.Item>
                <Form.Item label="部门简介(中文)">
                    {getFieldDecorator('organizationDesc', {
                        initialValue: getPath(info, 'organizationDesc', '')
                    })(
                        <LimitInput
                            area
                            maxLength={10000}
                            placeholder="请输入部门简介(中文)"
                            autoSize={{ minRows: 3, maxRows: 6 }}
                        />
                    )}
                </Form.Item>
                <Form.Item label="部门简介(英文)">
                    {getFieldDecorator('organizationDescEnglish', {
                        initialValue: getPath(info, 'organizationDescEnglish', '')
                    })(
                        <LimitInput
                            area
                            maxLength={10000}
                            placeholder="请输入部门简介(英文)"
                            autoSize={{ minRows: 3, maxRows: 6 }}
                        />
                    )}
                </Form.Item>
            </Form>
        </Spin>
    );
};

export default Department;
